/**
 * @file singleplayergamewidget.cpp
 * @brief 单人游戏界面组件实现文件
 *
 * 基于Snake Game服务文档实现的单人模式游戏界面
 */

#include "singleplayergamewidget.h"
#include <QApplication>
#include <QJsonDocument>
#include <QDebug>
#include <QPainterPath>
#include <QFontMetrics>

/**
 * @brief SinglePlayerGameWidget构造函数
 * @param parent 父窗口指针
 */
SinglePlayerGameWidget::SinglePlayerGameWidget(QWidget *parent)
    : QWidget(parent)
    , m_gameOver(false)
    , m_gamePaused(false)
    , m_finalScore(0)
    , m_hasServerState(false)
    , m_mainLayout(nullptr)
    , m_topLayout(nullptr)
    , m_scoreLabel(nullptr)
    , m_timeLabel(nullptr)
    , m_statusLabel(nullptr)
    , m_restartButton(nullptr)
    , m_exitButton(nullptr)
    , m_renderTimer(new QTimer(this))
    , m_backgroundColor(26, 26, 46)
    , m_gridColor(76, 175, 80, 50)
    , m_snakeHeadColor(76, 175, 80)
    , m_snakeBodyColor(102, 187, 106)
{
    // === 设置窗口属性 ===
    setWindowTitle("Snake Game - 单人模式");
    setMinimumSize(800, 600);
    setFocusPolicy(Qt::StrongFocus);

    // === 初始化游戏状态 ===
    m_currentState.map_size = QSize(40, 30);  // 根据文档默认配置
    m_currentState.status = 0;  // WAITING
    m_currentState.mode = 0;    // SINGLE_PLAYER
    m_currentState.enable_walls = true;
    m_currentState.tick_count = 0;

    // === 初始化食物颜色 ===
    m_foodColors[0] = QColor(255, 87, 34);   // NORMAL - 橙色
    m_foodColors[1] = QColor(255, 215, 0);   // BONUS - 金色
    m_foodColors[2] = QColor(33, 150, 243);  // SPEED - 蓝色
    m_foodColors[3] = QColor(156, 39, 176);  // SLOW - 紫色

    // === 设置UI ===
    setupUI();
    loadImages();

    // === 设置渲染定时器 (60FPS) ===
    m_renderTimer->setInterval(16);  // 16ms = ~60FPS
    connect(m_renderTimer, &QTimer::timeout, this, &SinglePlayerGameWidget::onRenderTimer);

    qDebug() << "SinglePlayerGameWidget: 初始化完成";
}

/**
 * @brief SinglePlayerGameWidget析构函数
 */
SinglePlayerGameWidget::~SinglePlayerGameWidget()
{
    if (m_renderTimer) {
        m_renderTimer->stop();
    }
}

/**
 * @brief 设置UI界面
 */
void SinglePlayerGameWidget::setupUI()
{
    m_mainLayout = new QVBoxLayout(this);
    m_mainLayout->setContentsMargins(10, 10, 10, 10);
    m_mainLayout->setSpacing(10);

    // === 顶部信息栏 ===
    m_topLayout = new QHBoxLayout();
    
    m_scoreLabel = new QLabel("分数: 0");
    m_scoreLabel->setStyleSheet("color: white; font-size: 16px; font-weight: bold;");
    
    m_timeLabel = new QLabel("时间: 00:00");
    m_timeLabel->setStyleSheet("color: white; font-size: 16px; font-weight: bold;");
    
    m_statusLabel = new QLabel("等待开始");
    m_statusLabel->setStyleSheet("color: white; font-size: 16px; font-weight: bold;");
    
    m_restartButton = new QPushButton("重新开始");
    m_restartButton->setStyleSheet(
        "QPushButton {"
        "    background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #4CAF50, stop:1 #45A049);"
        "    border: none; border-radius: 8px; color: white;"
        "    font-size: 14px; font-weight: bold; padding: 8px 16px;"
        "}"
        "QPushButton:hover {"
        "    background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #45A049, stop:1 #3E8E41);"
        "}"
    );
    
    m_exitButton = new QPushButton("退出游戏");
    m_exitButton->setStyleSheet(
        "QPushButton {"
        "    background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #F44336, stop:1 #D32F2F);"
        "    border: none; border-radius: 8px; color: white;"
        "    font-size: 14px; font-weight: bold; padding: 8px 16px;"
        "}"
        "QPushButton:hover {"
        "    background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #EF5350, stop:1 #F44336);"
        "}"
    );

    m_topLayout->addWidget(m_scoreLabel);
    m_topLayout->addWidget(m_timeLabel);
    m_topLayout->addWidget(m_statusLabel);
    m_topLayout->addStretch();
    m_topLayout->addWidget(m_restartButton);
    m_topLayout->addWidget(m_exitButton);

    m_mainLayout->addLayout(m_topLayout);
    m_mainLayout->addStretch();  // 游戏区域占据剩余空间

    // === 连接信号槽 ===
    connect(m_restartButton, &QPushButton::clicked, this, &SinglePlayerGameWidget::onRestartClicked);
    connect(m_exitButton, &QPushButton::clicked, this, &SinglePlayerGameWidget::onExitClicked);
}

/**
 * @brief 加载图片资源
 */
void SinglePlayerGameWidget::loadImages()
{
    // 这里可以加载实际的图片资源
    // 目前使用代码绘制的方式
    qDebug() << "SinglePlayerGameWidget: 图片资源加载完成";
}

/**
 * @brief 更新游戏状态
 * @param state 新的游戏状态
 */
void SinglePlayerGameWidget::updateGameState(const GameState& state)
{
    // 检查是否是第一次收到有效的服务器状态
    if (!m_hasServerState && (!state.snakes.isEmpty() || !state.foods.isEmpty())) {
        qDebug() << "SinglePlayerGameWidget: 收到第一帧服务器数据，清空测试数据";
        m_hasServerState = true;

        // 清空之前的测试数据
        m_currentState.snakes.clear();
        m_currentState.foods.clear();
    }

    m_currentState = state;

    // === 更新UI显示 ===
    if (!m_currentState.snakes.isEmpty()) {
        m_scoreLabel->setText(QString("分数: %1").arg(m_currentState.snakes.first().score));
    }

    // === 计算游戏时间 ===
    int seconds = m_currentState.tick_count / 10;  // 100ms per tick
    int minutes = seconds / 60;
    seconds %= 60;
    m_timeLabel->setText(QString("时间: %1:%2")
                        .arg(minutes, 2, 10, QChar('0'))
                        .arg(seconds, 2, 10, QChar('0')));

    // === 更新状态显示 ===
    QString statusText;
    switch (m_currentState.status) {
        case 0: statusText = "等待开始"; break;
        case 1: statusText = "游戏中"; break;
        case 2: statusText = "已暂停"; break;
        case 3: statusText = "游戏结束"; m_gameOver = true; break;
    }
    m_statusLabel->setText(statusText);

    // === 触发重绘 ===
    update();
}

/**
 * @brief 显示游戏结束界面
 * @param final_score 最终分数
 */
void SinglePlayerGameWidget::showGameOver(int final_score)
{
    m_gameOver = true;
    m_finalScore = final_score;
    m_statusLabel->setText("游戏结束");
    update();
}

/**
 * @brief 重置游戏
 */
void SinglePlayerGameWidget::resetGame()
{
    m_gameOver = false;
    m_gamePaused = false;
    m_finalScore = 0;
    m_currentState.snakes.clear();
    m_currentState.foods.clear();
    m_currentState.tick_count = 0;
    m_currentState.status = 0;
    
    m_scoreLabel->setText("分数: 0");
    m_timeLabel->setText("时间: 00:00");
    m_statusLabel->setText("等待开始");
    
    update();
}

/**
 * @brief 开始游戏
 */
void SinglePlayerGameWidget::startGame()
{
    qDebug() << "SinglePlayerGameWidget: 开始游戏";
    m_gameOver = false;
    m_gamePaused = false;
    m_hasServerState = false;  // 重置服务器状态标志
    m_currentState.status = 1;  // PLAYING

    // === 不再注入任何默认测试数据，等待服务器状态 ===
    m_statusLabel->setText("等待服务器...");

    // === 启动渲染定时器 ===
    m_renderTimer->start();
    setFocus();

    // === 触发重绘 ===
    update();

    qDebug() << "SinglePlayerGameWidget: 游戏启动，等待服务器首帧";
}

/**
 * @brief 暂停/恢复游戏
 */
void SinglePlayerGameWidget::togglePause()
{
    m_gamePaused = !m_gamePaused;
    if (m_gamePaused) {
        emit pauseRequested();
    } else {
        emit resumeRequested();
    }
}

/**
 * @brief 计算单元格大小
 */
void SinglePlayerGameWidget::calculateCellSize()
{
    // === 计算游戏区域 ===
    QRect availableRect = rect();
    availableRect.adjust(20, 60, -20, -20);  // 留出边距和顶部UI空间

    // === 根据地图大小计算单元格大小 ===
    int cellWidth = availableRect.width() / m_currentState.map_size.width();
    int cellHeight = availableRect.height() / m_currentState.map_size.height();
    
    // === 使用较小的值保持正方形 ===
    int cellSize = qMin(cellWidth, cellHeight);
    m_cellSize = QSize(cellSize, cellSize);

    // === 计算游戏区域居中位置 ===
    int gameWidth = m_cellSize.width() * m_currentState.map_size.width();
    int gameHeight = m_cellSize.height() * m_currentState.map_size.height();
    
    int startX = (width() - gameWidth) / 2;
    int startY = 60 + (availableRect.height() - gameHeight) / 2;
    
    m_gameArea = QRect(startX, startY, gameWidth, gameHeight);
}

/**
 * @brief 从JSON解析游戏状态
 * @param json JSON对象
 * @return 游戏状态
 */
SinglePlayerGameWidget::GameState SinglePlayerGameWidget::GameState::fromJson(const QJsonObject& json)
{
    GameState state;

    // === 解析蛇数据 ===
    QJsonArray snakes_array = json["snakes"].toArray();
    for (const auto& snake_value : snakes_array) {
        QJsonObject snake_obj = snake_value.toObject();
        Snake snake;
        snake.player_id = snake_obj["player_id"].toString();
        snake.direction = snake_obj["direction"].toInt();
        snake.score = snake_obj["score"].toInt();
        snake.is_alive = snake_obj["is_alive"].toBool();

        // === 解析蛇身位置 ===
        QJsonArray body_array = snake_obj["body"].toArray();
        for (const auto& pos_value : body_array) {
            QJsonObject pos_obj = pos_value.toObject();
            snake.body.append(QPoint(pos_obj["x"].toInt(), pos_obj["y"].toInt()));
        }

        state.snakes.append(snake);
    }

    // === 解析食物数据 ===
    QJsonArray foods_array = json["foods"].toArray();
    for (const auto& food_value : foods_array) {
        QJsonObject food_obj = food_value.toObject();
        Food food;
        QJsonObject pos_obj = food_obj["position"].toObject();
        food.position = QPoint(pos_obj["x"].toInt(), pos_obj["y"].toInt());
        food.type = food_obj["type"].toInt();
        food.value = food_obj["value"].toInt();

        state.foods.append(food);
    }

    // === 解析地图和游戏状态 ===
    QJsonObject map_obj = json["map"].toObject();
    state.map_size = QSize(map_obj["width"].toInt(), map_obj["height"].toInt());
    state.enable_walls = map_obj["enable_walls"].toBool();

    state.status = json["status"].toInt();
    state.tick_count = json["tick_count"].toInt();
    state.mode = json["mode"].toInt();

    return state;
}

/**
 * @brief 绘制事件处理
 * @param event 绘制事件
 */
void SinglePlayerGameWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    // === 绘制背景 ===
    painter.fillRect(rect(), m_backgroundColor);

    // === 计算单元格大小 ===
    calculateCellSize();

    // === 绘制游戏区域边框 ===
    painter.setPen(QPen(QColor(76, 175, 80), 2));
    painter.drawRect(m_gameArea);

    // === 绘制网格 ===
    drawGrid(painter);

    // === 绘制食物 ===
    for (const auto& food : m_currentState.foods) {
        drawFood(painter, food);
    }

    // === 绘制蛇 ===
    for (const auto& snake : m_currentState.snakes) {
        if (snake.is_alive) {
            drawSnake(painter, snake);
        }
    }

    // === 绘制游戏结束界面 ===
    if (m_gameOver) {
        drawGameOverScreen(painter);
    }
}

/**
 * @brief 绘制网格
 * @param painter 绘图器
 */
void SinglePlayerGameWidget::drawGrid(QPainter& painter)
{
    painter.setPen(QPen(m_gridColor, 1));

    // === 绘制垂直线 ===
    for (int x = 0; x <= m_currentState.map_size.width(); ++x) {
        int lineX = m_gameArea.x() + x * m_cellSize.width();
        painter.drawLine(lineX, m_gameArea.y(), lineX, m_gameArea.bottom());
    }

    // === 绘制水平线 ===
    for (int y = 0; y <= m_currentState.map_size.height(); ++y) {
        int lineY = m_gameArea.y() + y * m_cellSize.height();
        painter.drawLine(m_gameArea.x(), lineY, m_gameArea.right(), lineY);
    }
}

/**
 * @brief 绘制蛇
 * @param painter 绘图器
 * @param snake 蛇数据
 */
void SinglePlayerGameWidget::drawSnake(QPainter& painter, const GameState::Snake& snake)
{
    if (snake.body.isEmpty()) return;

    // === 绘制蛇头 ===
    QPoint headPos = snake.body.first();
    QRect headRect(m_gameArea.x() + headPos.x() * m_cellSize.width(),
                   m_gameArea.y() + headPos.y() * m_cellSize.height(),
                   m_cellSize.width(), m_cellSize.height());

    painter.setBrush(m_snakeHeadColor);
    painter.setPen(QPen(m_snakeHeadColor.darker(150), 2));
    painter.drawRoundedRect(headRect.adjusted(2, 2, -2, -2), 4, 4);

    // === 绘制眼睛 ===
    painter.setBrush(Qt::white);
    painter.setPen(Qt::NoPen);
    QRect leftEye, rightEye;

    switch (snake.direction) {
        case 0: // UP
            leftEye = QRect(headRect.x() + 4, headRect.y() + 4, 4, 4);
            rightEye = QRect(headRect.x() + headRect.width() - 8, headRect.y() + 4, 4, 4);
            break;
        case 1: // DOWN
            leftEye = QRect(headRect.x() + 4, headRect.y() + headRect.height() - 8, 4, 4);
            rightEye = QRect(headRect.x() + headRect.width() - 8, headRect.y() + headRect.height() - 8, 4, 4);
            break;
        case 2: // LEFT
            leftEye = QRect(headRect.x() + 4, headRect.y() + 4, 4, 4);
            rightEye = QRect(headRect.x() + 4, headRect.y() + headRect.height() - 8, 4, 4);
            break;
        case 3: // RIGHT
            leftEye = QRect(headRect.x() + headRect.width() - 8, headRect.y() + 4, 4, 4);
            rightEye = QRect(headRect.x() + headRect.width() - 8, headRect.y() + headRect.height() - 8, 4, 4);
            break;
    }

    painter.drawEllipse(leftEye);
    painter.drawEllipse(rightEye);

    // === 绘制蛇身 ===
    for (int i = 1; i < snake.body.size(); ++i) {
        QPoint pos = snake.body[i];
        QRect cellRect(m_gameArea.x() + pos.x() * m_cellSize.width(),
                       m_gameArea.y() + pos.y() * m_cellSize.height(),
                       m_cellSize.width(), m_cellSize.height());

        // === 计算渐变颜色 ===
        double fadeRatio = 1.0 - (double(i) / snake.body.size()) * 0.3;
        QColor segmentColor = m_snakeBodyColor;
        segmentColor = segmentColor.darker(100 + (1.0 - fadeRatio) * 30);

        painter.setBrush(segmentColor);
        painter.setPen(QPen(segmentColor.darker(150), 1));
        painter.drawRoundedRect(cellRect.adjusted(3, 3, -3, -3), 3, 3);
    }
}

/**
 * @brief 绘制食物
 * @param painter 绘图器
 * @param food 食物数据
 */
void SinglePlayerGameWidget::drawFood(QPainter& painter, const GameState::Food& food)
{
    QRect foodRect(m_gameArea.x() + food.position.x() * m_cellSize.width(),
                   m_gameArea.y() + food.position.y() * m_cellSize.height(),
                   m_cellSize.width(), m_cellSize.height());

    // === 根据食物类型选择颜色 ===
    int colorIndex = qBound(0, food.type, 3);
    QColor foodColor = m_foodColors[colorIndex];

    painter.setBrush(foodColor);
    painter.setPen(QPen(foodColor.darker(150), 2));
    painter.drawEllipse(foodRect.adjusted(4, 4, -4, -4));

    // === 绘制分值文字（奖励食物） ===
    if (food.type == 1 && food.value > 1) {  // BONUS食物
        painter.setPen(Qt::white);
        painter.setFont(QFont("Arial", 8, QFont::Bold));
        painter.drawText(foodRect, Qt::AlignCenter, QString("+%1").arg(food.value));
    }
}

/**
 * @brief 绘制游戏结束界面
 * @param painter 绘图器
 */
void SinglePlayerGameWidget::drawGameOverScreen(QPainter& painter)
{
    // === 绘制半透明遮罩 ===
    painter.fillRect(rect(), QColor(0, 0, 0, 150));

    // === 绘制游戏结束文字 ===
    painter.setPen(Qt::white);
    painter.setFont(QFont("Arial", 32, QFont::Bold));

    QRect textRect = rect();
    painter.drawText(textRect, Qt::AlignCenter, "游戏结束");

    // === 绘制最终分数 ===
    painter.setFont(QFont("Arial", 18));
    textRect.translate(0, 60);
    painter.drawText(textRect, Qt::AlignCenter, QString("最终分数: %1").arg(m_finalScore));

    // === 绘制提示信息 ===
    painter.setFont(QFont("Arial", 14));
    textRect.translate(0, 40);
    painter.drawText(textRect, Qt::AlignCenter, "点击 '重新开始' 再来一局");
}

/**
 * @brief 键盘按下事件处理
 * @param event 键盘事件
 */
void SinglePlayerGameWidget::keyPressEvent(QKeyEvent *event)
{
    if (m_gameOver || m_gamePaused) {
        return;
    }

    // === 方向控制键处理 ===
    int direction = -1;
    switch (event->key()) {
        case Qt::Key_W:
        case Qt::Key_Up:
            direction = 0;  // UP
            break;
        case Qt::Key_S:
        case Qt::Key_Down:
            direction = 1;  // DOWN
            break;
        case Qt::Key_A:
        case Qt::Key_Left:
            direction = 2;  // LEFT
            break;
        case Qt::Key_D:
        case Qt::Key_Right:
            direction = 3;  // RIGHT
            break;
        case Qt::Key_Space:
            togglePause();
            event->accept();
            return;
        case Qt::Key_R:
            emit restartRequested();
            event->accept();
            return;
        case Qt::Key_Escape:
            emit exitGameRequested();
            event->accept();
            return;
    }

    if (direction != -1) {
        qDebug() << "SinglePlayerGameWidget: 发送方向变化:" << direction;
        emit directionChanged(direction);
        event->accept();
    } else {
        QWidget::keyPressEvent(event);
    }
}

/**
 * @brief 窗口大小改变事件处理
 * @param event 大小改变事件
 */
void SinglePlayerGameWidget::resizeEvent(QResizeEvent *event)
{
    QWidget::resizeEvent(event);
    calculateCellSize();
    update();
}

/**
 * @brief 渲染定时器槽
 */
void SinglePlayerGameWidget::onRenderTimer()
{
    // === 计算FPS ===
    static qint64 lastFrameTime = 0;
    static int frameCount = 0;
    static double currentFPS = 0.0;
    
    qint64 currentTime = QDateTime::currentMSecsSinceEpoch();
    frameCount++;
    
    if (lastFrameTime > 0) {
        qint64 elapsed = currentTime - lastFrameTime;
        if (elapsed >= 1000) { // 每秒更新一次FPS
            currentFPS = frameCount * 1000.0 / elapsed;
            frameCount = 0;
            lastFrameTime = currentTime;
            
            // 更新状态显示
            if (m_statusLabel) {
                m_statusLabel->setText(QString("游戏中 - FPS: %1").arg(currentFPS, 0, 'f', 1));
            }
            
            qDebug() << "SinglePlayerGameWidget: FPS=" << currentFPS;
        }
    } else {
        lastFrameTime = currentTime;
    }
    
    // 触发重绘
    update();
}

/**
 * @brief 重新开始按钮点击
 */
void SinglePlayerGameWidget::onRestartClicked()
{
    qDebug() << "SinglePlayerGameWidget: 重新开始游戏";
    emit restartRequested();
}

/**
 * @brief 退出按钮点击
 */
void SinglePlayerGameWidget::onExitClicked()
{
    qDebug() << "SinglePlayerGameWidget: 退出游戏";
    emit exitGameRequested();
}
